package su.myspringapps.onlineschool.repository;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import su.myspringapps.onlineschool.entity.Student;

import javax.persistence.NoResultException;

import static org.hibernate.resource.transaction.spi.TransactionStatus.ACTIVE;
import static org.hibernate.resource.transaction.spi.TransactionStatus.MARKED_ROLLBACK;

/**
 * Класс HQLStudentRepository, расширяет класс {@link StudentRepository}
 * <p/>
 * Выполняет те же функции, что и {@link StudentRepository}, только с помощью языка <b>HQL</b>
 * (нужен для изучения последнего)
 * <p/>
 *
 * @author petr.mikhailin
 * created 29.05.2024 9:07
 */
@Repository
public class HQLStudentRepository extends StudentRepository {

    @Autowired
    public HQLStudentRepository(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    public void updateParameter(Integer id, String paramName, Object paramValue) throws Exception {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            session.createQuery(String.format("UPDATE Student SET %s = :paramValue WHERE id = :id ", paramName))
                    .setParameter("paramValue", paramValue)
                    .setParameter("id", id)
                    .executeUpdate();
        } catch (Exception e) {
            if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
                transaction.rollback();
            }
            throw e;
        } finally {
            transaction.commit();
            session.close();
        }
    }

    public void deleteById(Integer id) throws Exception {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            session.createQuery("DELETE Student WHERE id= :id ").setParameter("id", id).executeUpdate();
        } catch (Exception e) {
            if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
                transaction.rollback();
            }
            throw e;
        } finally {
            transaction.commit();
            session.close();
        }
    }

    @Override
    public Student findById(Integer id) throws Exception {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student;
        try {
            student = session.createQuery("FROM Student WHERE id=:id", Student.class).setParameter("id", id)
                    .getSingleResult();
        } catch (NoResultException ex) {
            student = null;
        }
        transaction.commit();
        session.close();
        return student;
    }
}
